package com.p2l.letterblocks;

import java.util.Calendar;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;

public class Bear extends Sprite {
	private Block block;
	private Vector lastKnownDirection;
	private Bitmap spritesheet, head, body, legs, belt, accessories;
	private int frameWidth, frameHeight, frame = 0, row = 0;
	private boolean isMoving;
	private boolean isJumping;
	private long timeStarted;
	private Rect src, dst;


	public Bear(float x, float y, float height, float width, Bitmap spritesheet) {
		super(x, y, height, width, spritesheet);
		this.spritesheet = spritesheet;
		lastKnownDirection = new Vector(1, 0);
		timeStarted = Calendar.getInstance().getTimeInMillis();
		frameWidth = spritesheet.getWidth() / 12;
		frameHeight = spritesheet.getHeight() / 4;
		dst = new Rect((int) (x - (getWidth() / 2)), 0,	(int) (x + (getWidth() / 2)), (int) (0 + getHeight()));
		src = new Rect(frame * frameWidth, 0, (frame + 1) * frameWidth, frameHeight);
	}

	public Block getBlock() {
		return block;
	}

	public void setBlock(Block block) {
		this.block = block;
	}

	public Vector getLastKnownDirection() {
		return lastKnownDirection;
	}

	public void setLastKnownDirection(Vector lastKnownDirection) {
		this.lastKnownDirection = lastKnownDirection;
	}
	
	public Bitmap getSpritesheet() {
		return spritesheet;
	}

	public void setSpritesheet(Bitmap spritesheet) {
		this.spritesheet = spritesheet;
	}

	public boolean isMoving() {
		return isMoving;
	}

	public void setMoving(boolean isMoving) {
		this.isMoving = isMoving;
	}
	
	public boolean isJumping() {
		return isJumping;
	}

	public void setJumping(boolean isJumping) {
		this.isJumping = isJumping;
	}
	

	public long getTimeStarted() {
		return timeStarted;
	}

	public void setDst(int left, int top, int right, int bot) {
		dst.left = left;
		dst.top = top;
		dst.right = right;
		dst.bottom = bot;
	}
	
	public Bitmap getHead() {
		return head;
	}

	public void setHead(Bitmap head) {
		this.head = head;
	}

	public Bitmap getBody() {
		return body;
	}

	public void setBody(Bitmap body) {
		this.body = body;
	}

	public Bitmap getLegs() {
		return legs;
	}

	public void setLegs(Bitmap legs) {
		this.legs = legs;
	}

	public Bitmap getBelt() {
		return belt;
	}

	public void setBelt(Bitmap belt) {
		this.belt = belt;
	}

	public Bitmap getAccessories() {
		return accessories;
	}

	public void setAccessories(Bitmap accessories) {
		this.accessories = accessories;
	}
	
	public void recycle() {
		if(spritesheet !=null) {
			spritesheet.recycle();
			spritesheet = null;
		
			if (accessories != null) {
				accessories.recycle();
				accessories = null;
			}
			if (head != null) {
				
				head.recycle();
				head = null;
			}
			if (body != null) {
				body.recycle();
				body = null;
			}
			if (legs != null) {
				legs.recycle();
				legs = null;
			}
			if (belt != null) {
				belt.recycle();
				belt = null;
			}
		}
	}

	@Override
	public void onDraw(Canvas c, int delta, float x) {
		long time = Calendar.getInstance().getTimeInMillis();
		float newY = super.getY() + (getVector().getY() * delta);

		// update bears destination
		setDst((int) (x - (getWidth() / 2)), (int) (newY), (int) (x + (getWidth() / 2)), (int) (newY + getHeight()));
		
		// update the Bear src 
		frame = (delta != -1 ? ((int)((time - delta) % 1000) / 84) : 0);
		
		updateAnimation();
		
		src.left = frame * frameWidth;
		src.top = row * frameHeight + 1;
		src.right = (frame + 1) * frameWidth;
		src.bottom = (row + 1) * frameHeight;

		c.drawBitmap(spritesheet, src, dst, super.getPaint());
		if (legs != null)
			c.drawBitmap(legs, src, dst, super.getPaint());
		if (body != null)
			c.drawBitmap(body, src, dst, super.getPaint());
		if (belt != null)
			c.drawBitmap(belt, src, dst, super.getPaint());
		if (accessories != null)
			c.drawBitmap(accessories, src, dst, super.getPaint());
		if (head != null)
			c.drawBitmap(head, src, dst, super.getPaint());
	}

	public void update(int delta) {
		getVector().setY(getVector().getY() + (GamePersistor.SCREEN_HEIGHT / Vector.GRAVITY) * delta);
		if (getVector().getY() > 0.4f)
			getVector().setY(0.4f);
		setY(getY() + getVector().getY() * delta);
		setX(getX() + getVector().getX() * delta);
		
		// floor collision detection
		float bottom = GamePersistor.SCREEN_HEIGHT - getHeight() - (GamePersistor.SCREEN_HEIGHT / 100 * GameView.BOTTOM);
		if (getY() > bottom) {
			setY(bottom);
			getVector().setY(0f);
		}

		// wall collision detection
		float right = GameView.GAME_WIDTH - getWidth();
		if (getX() <= 0 || getX() >= right) {
			setX((getX() < 0 ? 0 : getX()));
			setX((getX() > right ? right : getX()));
			getVector().setX(0f);
		}

		if (block != null) {
			if (getLastKnownDirection().getX() < 0)
				block.setX(getX() - block.getWidth() + (GameModel.FACTOR * 7));
			else
				block.setX(getX() + block.getWidth() - (GameModel.FACTOR * 7));
			
			block.setY((getY() + (getHeight() / 3 * 2)) - (block.getHeight() / 2));
			block.getVector().setY(0f);

			// wall collision on the block
			right = GameView.GAME_WIDTH - block.getWidth();
			if (block.getX() <= 0 || block.getX() >= right) {
				if (block.getX() < 0) {
					block.setX(0f);
					setX(block.getX() + block.getWidth() - (GameModel.FACTOR * 7));
				} else if (block.getX() > right) {
					block.setX(right);
					setX(right - block.getWidth() + (GameModel.FACTOR * 7));
				}
				super.getVector().setX(0f);
			}
		}
	}	

	public boolean isColliding(Sprite s) {
		// collision detection on the block if the bear holds one
		try {
			if (block != null) {
				if (block == s)
					return false;
				else if (block.getX() <= s.getX() + s.getWidth() && block.getX() + block.getWidth() >= s.getX()	&& block.getY() <= s.getY() + s.getHeight() && block.getY() + block.getHeight() >= s.getY())
					return true;
			}
		} catch (NullPointerException e) {
			return false;
		}
		// collision detection on the bear
		if (getX() <= s.getX() + s.getWidth() && getX() + getWidth() >= s.getX() && getY() <= s.getY() + s.getHeight() && getY() + getHeight() >= s.getY())
			return true;
		else
			return false;
	}
	
	// update animation
	public void updateAnimation() {
		// if bear is facing right
		if (getLastKnownDirection().getX() > 0) {
			// row 0 or 2 should be drawn
			// if bear moved
			if(isMoving) {
				// check if bear is jumping or falling
				if(isJumping) {
					// check if bear got a block
					if(getBlock() != null) {
						row = 2;
						frame = 3;
					} else {
						row = 0;
						frame = 3;
					}
					// he just moved	
				} else {
					// check if bear got a block
					if(getBlock() != null) {
						row = 2;
					} else {
						row = 0;
					}
				}
				// he is standing still
			} else {
				if(isJumping) {
					// check if bear got block
					if(getBlock() != null) {
						frame = 3;
						//Log.d("LetterBlocks", "He is standing still while jumping");
					} else {
						row = 0;
						frame = 3;
						//Log.d("LetterBlocks", "He is standing still");
					}	
				} else {
					// check if bear got a block
					if(getBlock() != null) {
						row = 2;
						frame = 0;
					} else {
						row = 0;
						frame = 0;
					}
				}	
			}
			
			// bear is facing left
			// row 1 or 3 should be drawn
		} else {
			// check if bear is moving
			if(isMoving) {
				// check if bear is jumping or falling
				if(isJumping) {
					// check if bear got block
					if(getBlock() != null) {
						row = 3;
						frame = 3;
						//Log.d("LetterBlocks", "He is standing still while jumping");
					} else {
						row = 1;
						frame = 3;
						//Log.d("LetterBlocks", "He is standing still");
					}
					
					// he just moved
				} else {
					// check if bear got a block
					if(getBlock() != null) {
						row = 3;
					} else {
						row = 1;
					}	
				}
				// he is standing still
			} else {
				if(isJumping) {
					// check if bear got a block
					if(getBlock() != null) {
						row = 3;
						frame = 3;
					} else {
						row = 1;
						frame = 3;
					}
				} else {
					// check if bear got block
					if(getBlock() != null) {
						row = 3;
						frame = 0;
					} else {
						row = 1;
						frame = 0;
					}
				}	
			}
		}
	}
}